import java.nio.ByteBuffer;


public class Node {
	private static final int T = 6;
	private int mNumKeys = 0;
	private int[] mKeys = new int[2 * T - 1];
	private Object[] mObjects = new Object[2 * T - 1];
	private int[] mChildNodePointers = new int[2 * T]; // Node pointers (offset)
	private boolean mIsLeafNode;
	private int mNextNodePointer; // Node pointer (offset)
	
	private int offset;
	
	private static final int headerLength = 4;

	private int rowLength = 2 + mKeys.length * DomainObjectChecker.DEFAULT_INT_LENGTH + mChildNodePointers.length * DomainObjectChecker.DEFAULT_INT_LENGTH;
	
	private BinaryFileIO indexWriter = new BinaryFileIO("users_ID.index", "user_ID.rsindex", headerLength, rowLength);
	
//	private Node(boolean mIsLeafNode, int mNumKeys, int[] mChildNodes, int[] mKeys, int offset) {
//		this.mIsLeafNode = mIsLeafNode;
//		this.mNumKeys = mNumKeys;
//		this.mChildNodePointers = mChildNodes;
//		this.mKeys = mKeys;
//		if (mIsLeafNode) this.mNextNode = mChildNodes[mChildNodes.length - 1]; 
//		this.offset = offset;
//	}
	
//	private String createStringRow() {
//		String isLeaf = mIsLeafNode ? StringUtils.rightPad("1", numberLength) : StringUtils.rightPad("0", numberLength);
//		String numKeys = StringUtils.rightPad(Integer.toString(mNumKeys), numberLength);
//		String row = isLeaf + numKeys;
//		for (int i = 0; i < mChildNodePointers.length; i++) {
//			row += StringUtils.rightPad(Integer.toString(mChildNodePointers[i]), numberLength);
//			if (i < mKeys.length)
//				row += StringUtils.rightPad(Integer.toString(mKeys[i]), numberLength);
//		}
//		return row;
//	}

	public int getmNumKeys() {
		return mNumKeys;
	}

	public void setmNumKeys(int mNumKeys) {
		this.mNumKeys = mNumKeys;
	}

	public int[] getmKeys() {
		return mKeys;
	}

	public void setmKeys(int[] mKeys) {
		this.mKeys = mKeys;
	}
	
	public void setmKey(int key, int index){
		this.mKeys[index] = key;
	}

	public Object[] getmObjects() {
		return mObjects;
	}
	
	public Object getmObject(int index) {
		return this.mObjects[index];
	}

	public void setmObjects(Object[] mObjects) {
		this.mObjects = mObjects;
	}
	
	public void setmObject(Object object, int index){
		this.mObjects[index] = object;
	}
	
	public Node getmChildNode(int mChildIndex) {
		int childNodeNumberRow = this.mChildNodePointers[mChildIndex];
		int childNodeOffset = headerLength+(childNodeNumberRow-1)*rowLength;
		byte[] row = indexWriter.readRow(childNodeOffset, rowLength);
		return indexWriter.toNode(row, childNodeNumberRow);		
	}
	
	public int getmChildNodeOffset(int mChildIndex) {
		return mChildNodePointers[mChildIndex];
	}

	public void setmChildNode(int mChildNodePointer, int index) {
		this.mChildNodePointers[index] = mChildNodePointer;
	}

	public boolean ismIsLeafNode() {
		return mIsLeafNode;
	}

	public void setmIsLeafNode(boolean mIsLeafNode) {
		this.mIsLeafNode = mIsLeafNode;
	}

	public Node getmNextNode() {
		return getmChildNode(this.mChildNodePointers.length - 1);
	}
	
	public int getmNextNodeOffset() {
		return this.mNextNodePointer;
	}

	public void setmNextNode(int mNextNodePointer) {
		this.mNextNodePointer = mNextNodePointer;
	}
	
	public int getOffset() {
		return offset;
	}

	public void setOffset(int offset) {
		this.offset = offset;
	}

	public int getmNumKey(int index) {
		return this.mKeys[index];
	}

	public void updateHeaderInFileForNode(){
		indexWriter.updateHeader(ByteBuffer.allocate(headerLength).putInt(this.getOffset()).array());
	}
	
	public void updateNodeInFile() {
		byte[] row = indexWriter.toByteArray(this, rowLength);
		if (offset == 0) {
			int offsetInFile = indexWriter.insertRow(row);
			offset = (offsetInFile - headerLength)/rowLength+1;
		} else {
			indexWriter.updateRow(row, (offset-1)*rowLength+headerLength);
		}
		
	}
}
